/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.gbvbahia.projeto.aop;

import org.apache.commons.lang3.time.DurationFormatUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/aop.html
 * Autodetecting aspects through component scanning You may register
 * aspect classes as regular beans in your Spring XML configuration,
 * or autodetect them through classpath scanning - just like any other
 * Spring-managed bean. However, note that the @Aspect annotation is
 * not sufficient for autodetection in the classpath: For that
 * purpose, you need to add a separate @Component annotation (or
 * alternatively a custom stereotype annotation that qualifies, as per
 * the rules of Spring's component scanner).
 *
 * @since v.1 19/05/2012
 * @author Guilherme
 */
@Aspect
@Component
public class LogTime {

    /**
     * Registra os eventos para debug em desenvolvimento.
     */
    private Logger logger = Logger.getLogger(LogTime.class);

    /**
     * Todos os métodos publicos dos beans Spring, do pacote
     * br.com.gbvbahia.projeto.beans e sub pacotes são interceptados
     * por este método para registrar o tempo de execução.<br>
     * Documentação:<br>
     * http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/aop.html
     *
     * @param pjp Injetado pelo Spring/AspectJ
     * @return O resultado do método.
     */
    @Around("execution(* br.com.gbvbahia.projeto.beans..*(..))")
    public Object logTimeBeans(ProceedingJoinPoint pjp) throws Throwable {
        String clazz = pjp.getTarget().getClass().getName();
        String method = pjp.getStaticPart().toShortString();
        StopWatch timeWatch = new StopWatch();
        timeWatch.start();
        try {
            return pjp.proceed();
        } finally {
            timeWatch.stop();
            String time = DurationFormatUtils.formatDuration(
                    timeWatch.getTime(), "HH:mm:ss");
            logger.info("Class: " + clazz + " Ass: " + method
                    + " Duração: " + time);
        }
    }
}
